package top.lingkang.finalsecurity.solonplugin.interceptor;

import org.noear.solon.Solon;
import org.noear.solon.core.aspect.Interceptor;
import org.noear.solon.core.aspect.Invocation;
import org.noear.solon.core.handle.Context;
import top.lingkang.finalsecurity.common.annotation.FinalCheck;
import top.lingkang.finalsecurity.common.base.FinalHttpProperties;
import top.lingkang.finalsecurity.common.constants.FinalConstants;
import top.lingkang.finalsecurity.common.error.FinalNotLoginException;
import top.lingkang.finalsecurity.common.utils.AuthUtils;
import top.lingkang.finalsecurity.solonplugin.FinalSecurityHolder;

/**
 * @author lingkang
 * Created by 2022/10/28
 * @since 3.0.0
 */
public class FinalCheckAnnotation implements Interceptor {
    public FinalHttpProperties properties;
    private final FinalSecurityHolder securityHolder = Solon.context().getBean(FinalSecurityHolder.class);

    @Override
    public Object doIntercept(Invocation inv) throws Throwable {
        if (properties.getCheckPathCache().getExcludePath().contains(Context.current().path())) {
            return inv.invoke();
        }

        if (!securityHolder.isLogin()) {
            throw new FinalNotLoginException(FinalConstants.NOT_LOGIN_MSG);
        }

        FinalCheck clazz = inv.target().getClass().getAnnotation(FinalCheck.class);
        if (clazz != null) {
            check(clazz);
        }

        FinalCheck method = inv.method().getAnnotation(FinalCheck.class);
        if (method != null) {
            check(method);
        }

        return inv.invoke();
    }

    private void check(FinalCheck check) {
        if (check.anyRole().length != 0)
            AuthUtils.checkRole(check.anyRole(), securityHolder.getRole());
        if (check.andRole().length != 0)
            AuthUtils.checkAndRole(check.andRole(), securityHolder.getRole());
    }
}
